/*
    DIMVisual, the Data Integration Model for Visualization of trace files.
    Copyright (c) 2008 Lucas Mello Schnorr <schnorr@gmail.com>

    This file is part of DIMVisual.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "IntegratorLib.h"

@implementation IntegratorLib
- (id) init
{
	self = [super init];
	bundleCenter = [[BundleCenter alloc] init];
	outputArrayAsLibrary = [[NSMutableArray alloc] init];
	headcenter = [[PajeHeaderCenter alloc] init];
	hierarchies = [[NSMutableArray alloc] init];
	return self;
}

/*
 *
 */
/*
- (id) initWithCommand: (Command *) command
{
	int i;
	NSMutableArray *ar;
	self = [self init];


	//NSDictionary *selfConf = [[command configuration] objectForKey: @"DIMVISUAL"];


	NSDictionary *bundleConf = [[command configuration] objectForKey: @"Bundles"];
	NSArray *allDataSources = [bundleConf allKeys];
	NSMutableArray *hierarchies = [[NSMutableArray alloc] init];
	for (i = 0; i < [allDataSources count]; i++){
		NSString *name = [allDataSources objectAtIndex: i];
		NSDictionary *conf=[bundleConf objectForKey: name];
		id<DataSource> ds;

		ds = [[NSClassFromString (name) alloc] initWithProvider: self];
		[ds setConfiguration: conf];
		[ordering add: ds];
		[hierarchies addObject: [ds hierarchy]];
	}

	hierarchy =  [[PajeHierarchy alloc] initFromDictionary:
				[self mergeHierarchies: hierarchies]];
	if (hierarchy == nil){
		NSLog (@"DIMVisual: Problem when creating hierarchy.");
		return nil;
	}

	ar = [hierarchy hierarchy];

	[outputArrayAsLibrary addObjectsFromArray: ar];

	[ar retain];
	for (i = 0; i < [ar count]; i++){
		[headcenter addHeader: [[ar objectAtIndex: i] header]];
	}
	[ar release];

	NSArray *hdefined = [hierarchy entityOfType: @"container"];
	[containers setObject: [NSMutableSet set] forKey: @"0"];
	for (i = 0; i < [hdefined count]; i++){
		[containers setObject: [NSMutableSet set] forKey: [hdefined objectAtIndex: i]];
	}




	return self;
}
*/

- (NSMutableArray *) configureHierarchy
{
	NSMutableArray *ret = [NSMutableArray array];

	/* Hierarchy */
	hierarchy = [[PajeHierarchy alloc] initFromDictionary:
				[self mergeHierarchies: hierarchies]];
       
	/* adding definition to output */ 
	[ret addObjectsFromArray: [hierarchy hierarchy]];
        
	int i;
	for (i = 0; i < [ret count]; i++){
		[headcenter addHeader: [[ret objectAtIndex: i] header]];
	}
        
	/* containers defined */
	NSArray *hdefined = [hierarchy entityOfType: @"container"];
	[containers setObject: [NSMutableSet set] forKey: @"0"];
	for (i = 0; i < [hdefined count]; i++){
		[containers setObject: [NSMutableSet set] forKey: [hdefined objectAtIndex: i]];
	}
	return ret;
}


/*
 *
 */
- (NSMutableArray *) convert
{
	static int flag = 0;
	NSMutableArray *ret2;
	NSMutableArray *ret = [NSMutableArray array];
	if (!flag){
		[ret addObjectsFromArray: [self configureHierarchy]];
		flag = 1;
	}
	ret2 = [ordering convert];
	if (ret2 == nil){
		[ret release];
		return nil;
	}
	[ret addObjectsFromArray: ret2];
	return ret;
}

- (GTimestamp *) time
{
	NSMutableArray *ret2;
	ret2 = [ordering convert];
	if (ret2 == nil){
		return nil;
	}else{
		[outputArrayAsLibrary addObjectsFromArray: ret2];
	}
	if ([ret2 count] > 0){
		return [[ret2 objectAtIndex: 0] time];
	}else{
		return nil;
	}
}

- (NSArray *) dimvisualBundlesAvailable
{
	return [bundleCenter listBundlesAvailable];
}

- (BOOL) loadDIMVisualBundle: (NSString *) name
{
	return [bundleCenter loadBundleWithName: name];
}

- (BOOL) isDIMVisualBundleLoaded: (NSString *) name
{
	return [bundleCenter isBundleWithNameLoaded: name];
}

- (NSDictionary *) getConfigurationOptionsFromDIMVisualBundle: (NSString *)name
{
	[self loadDIMVisualBundle: name];
	return [bundleCenter configurationForBundleWithName: name];
}

- (BOOL) setConfiguration: (NSDictionary *) conf forDIMVisualBundle: (NSString *) name
{
	NSString *principalClass;
	id<DataSource> ds;

	[bundleCenter configureBundle: name withThis: conf];
	principalClass = [bundleCenter principalClassOfBundleNamed: name];

	ds = [[NSClassFromString (principalClass) alloc] initWithProvider: self];
	if (ds == nil){
		NSString *str = [NSString stringWithFormat: @"IntegratorLib (%@): unable to init the main class (%@) of bundle %@", self, principalClass, name];
		[[NSException exceptionWithName: @"DIMVisual-Integrator" reason: str userInfo: nil] raise];
	}
	if (![ds setConfiguration: conf]){
		NSString *str = [NSString stringWithFormat: @"IntegratorLib (%@): unable to configure the bundle %@ with the configuration provided", self, name, conf];
		[[NSException exceptionWithName: @"DIMVisual-Integrator" reason: str userInfo: nil] raise];
	}else{
		[ordering add: ds];

		[hierarchies addObject: [ds hierarchy]];
		[ds release];
		return YES;
	}
	return NO;
}

- (void) dealloc
{
	[bundleCenter release];
	[outputArrayAsLibrary release];
	[headcenter release];
	[hierarchies release];
	[super dealloc];
}

- (PajeHeaderCenter *) pajeHeaderCenter
{
	return headcenter;
}
@end
